/**
 * Dispatch.cpp		Copyright _ 2001 Li Zhaoming. All rights reserved.
 * Implement the generic message and command dispatchers.
 */

#include "stdafx.h"

LRESULT dispatchDefault(EDWP, HWND, UINT, WPARAM, LPARAM);

/**
 * Call the function associated with a message.
 *
 * PARAMETERS:
 *		lpmsdi - Structure containing the message dispatch information.
 *		hwnd - The window handle
 *		uMessage - The message number
 *		wparam - Message specific data
 *		lparam - Message specific data
 *
 * RETURN VALUE:
 *		The value returned by the message function that was called.
 *
 * COMMENTS:
 *		Runs the table of messages stored in lpmsdi->rgmsd searching
 *		for a message number that matches uMessage. If a match is found,
 *		call the associated function. Otherwise, call dispatchDefault to
 *		call the default function, if any, associated with the message
 *		structure. In either case, return the value recieved from the
 *		message or default function.
 */
LRESULT dispatchMessage(LPMSDI lpmsdi, HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
{
	int imsd = 0;

	MSD *rgmsd = lpmsdi->rgmsd;
	int cmsd = lpmsdi->cmsd;

	for (imsd = 0; imsd < cmsd; imsd++)
	{
		if (rgmsd[imsd].uMessage == uMessage)
			return rgmsd[imsd].pfnmsg(hwnd, uMessage, wparam, lparam);
	}

	return dispatchDefault(lpmsdi->edwp, hwnd, uMessage, wparam, lparam);
}

/**
 * Call the function associated with a command.
 *
 * PARAMETERS:
 *		lpcmdi - Structure containing the command dispatch information.
 *		hwnd - The window handle
 *		GET_WM_COMMAND_ID(wparam, lparam) - Identifier of the menu item,
 *		control, or accelerator.
 *		GET_WM_COMMAND_CMD(wparam, lparam) - Notification code.
 *		GET_WM_COMMAND_HWND(wparam, lparam) - The control handle or NULL.
 *
 * RETURN VALUE:
 *		The value returned by the command function that was called.
 *
 * COMMENTS:
 *		Runs the table of commands stored in lpcmdi->rgcmd searching
 *		for a command number that matches wCommand. If a match is found,
 *		call the associated function. Otherwise, call dispatchDefault to
 *		call the default function, if any, associated with the command
 *		structure. In either case, return the value recieved from the
 *		command or default function.
 */
LRESULT dispatchCommand(LPCMDI lpcmdi, HWND hwnd, WPARAM wparam, LPARAM lparam)
{
	LRESULT lRet = 0;
	WORD	wCommand = GET_WM_COMMAND_ID(wparam, lparam);
	int	icmd;

	CMD *rgcmd = lpcmdi->rgcmd;
	int ccmd = lpcmdi->ccmd;

	// Message packing of wparam and lparam have changed for Win32,
	// so use the GET_WM_COMMAND macro to unpack the commnad
	for (icmd = 0; icmd < ccmd; icmd++)
	{
		if (rgcmd[icmd].wCommand == wCommand)
		{
			return rgcmd[icmd].pfncmd(hwnd,
								wCommand,
								GET_WM_COMMAND_CMD(wparam, lparam),
								GET_WM_COMMAND_HWND(wparam, lparam));
		}
	}

	return dispatchDefault(lpcmdi->edwp, hwnd, WM_COMMAND, wparam, lparam);
}

/**
 * Call the appropriate default window procedure.
 *
 * PARAMETERS:
 *		edwp - Enumerate specifying the appropriate default winow procedure.
 *		hwnd - The window handle
 *		uMessage - The message number
 *		wparam - Message specific data
 *		lparam - Message specific data
 *
 * RETURN VALUE:
 *		If there is a default proc, return the value returned by the
 *		default proc. Otherwise, return 0.
 *
 * COMMENTS:
 *		Calls the default procedure associated with edwp using the specified
 *		parameters.
 */
LRESULT dispatchDefault(EDWP edwp, HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
{
	switch (edwp)
	{
		case edwpNone:
			return 0;
		case edwpWindow:
			return DefWindowProc(hwnd, uMessage, wparam, lparam);
		case edwpDialog:
			return DefDlgProc(hwnd, uMessage, wparam, lparam);
		case edwpMDIFrame:
			return DefFrameProc(hwnd, hwndMDIClient, uMessage, wparam, lparam);
		case edwpMDIChild:
			return DefMDIChildProc(hwnd, uMessage, wparam, lparam);
	}
	return 0;
}
